import os
import re
import time

import torch


def abs_rel_path_concat(abs_path, relative_path):
    return os.path.normpath(
        os.path.join(os.path.dirname(abs_path), relative_path))


def path_check(file_path):
    flie_folder = os.path.dirname(os.path.abspath(file_path)) if file_path[-1] != '/' else os.path.abspath(file_path)
    if not os.path.exists(flie_folder):
        os.makedirs(flie_folder)


def save_model(model,
               epoch_id,
               optimizer,
               max_acc,
               min_loss,
               subdir="",
               pt_name="model.pt"):
    """ 保存模型 """
    # https://zhuanlan.zhihu.com/p/107203828
    subdir = "./trainning_tasks/" + subdir
    save_dir = abs_rel_path_concat(os.path.abspath(__file__),
                                   subdir + "/" + pt_name)
    path_check(save_dir)
    with open(os.path.join(os.path.dirname(save_dir), 'train.log'),
              'a+') as log:
        msg = "[{}] epoch : {}, acc : {:.3f}".format(
            time.strftime("%m-%d %H:%M:%S", time.localtime()), epoch_id,
            max_acc)
        log.write(msg + '\n')

    torch.save(
        {
            'epoch': epoch_id,
            'model_state_dict': model.state_dict(),
            'optimizer_state_dict': optimizer.state_dict(),
            'min_loss': min_loss,
        }, save_dir)
    print("model " + str(save_dir) + "saved")


def natural_key(string_):
    """See http://www.codinghorror.com/blog/archives/001018.html"""
    return [
        int(s) if s.isdigit() else s
        for s in re.split(r'(\d+)', string_.lower())
    ]
